#include "TriangleTest.h"
#include "Structures.h"
#include "TestPS.h";
#include "TestVS.h";
#include "SystemClass.h"
#include "ShaderManager.h"

TriangleTest::TriangleTest(void)
{
	D3DXMatrixIdentity(&m_worldMatrix);
	
	m_indexBuffer = 0;
	m_vertexBuffer = 0;
}


TriangleTest::~TriangleTest(void)
{
}

bool TriangleTest::Initialize(ID3D11Device* device)
{
	bool result;
	hasTexture = false;

	result = InitializeBuffers(device);
	if (!result)
	{
		return false;
	}

	result = InitializeShaders(device);
	if (!result)
	{
		return false;
	}
	return true;
}

void TriangleTest::Shutdown()
{
	ShutdownBuffers();
	return;
}

bool TriangleTest::Update()
{
	return true;
}

void TriangleTest::Render(ID3D11DeviceContext* deviceContext, D3DXMATRIX viewMatrix, D3DXMATRIX projectionMatrix)
{
	// do ALL the render works
	RenderBuffers(deviceContext);
	// Render the model using the color shader.
	m_vs->SetRenderParameters(deviceContext, m_worldMatrix, viewMatrix, projectionMatrix);
	m_ps->SetRenderParameters(deviceContext, NULL);
	deviceContext->DrawIndexed(m_indexCount, 0, 0);
}

int TriangleTest::GetIndexCount()
{
	return m_indexCount;
}

bool TriangleTest::InitializeBuffers(ID3D11Device* device)
{
	VertexType* vertices;
	unsigned long* indices;
	D3D11_BUFFER_DESC vertexBufferDesc, indexBufferDesc;
	D3D11_SUBRESOURCE_DATA vertexData, indexData;
	HRESULT result;

	// Set the number of vertices in the vertex array.
	m_vertexCount = 3;

	// Set the number of indices in the index array.
	m_indexCount = 3;

	// Create the vertex array.
	vertices = new VertexType[m_vertexCount];
	if(!vertices)
	{
		return false;
	}

	// Create the index array.
	indices = new unsigned long[m_indexCount];
	if(!indices)
	{
		return false;
	}

	vertices[0].position = D3DXVECTOR3(-40.0f, 0.0f, -30.0f);  // Bottom left.
	vertices[0].color = D3DXVECTOR4(0.0f, 1.0f, 0.0f, 1.0f);

	vertices[1].position = D3DXVECTOR3(0.0f, 0.0f, 30.0f);  // Top middle.
 	vertices[1].color = D3DXVECTOR4(1.0f, 0.0f, 0.0f, 1.0f);

	vertices[2].position = D3DXVECTOR3(40.0f, 0.0f, -30.0f);  // Bottom right.
	vertices[2].color = D3DXVECTOR4(0.0f, 0.0f, 1.0f, 1.0f);

	// Load the index array with data.
	indices[0] = 0;  // Bottom left.
	indices[1] = 1;  // Top middle.
	indices[2] = 2;  // Bottom right.

	// Set up the description of the static vertex buffer.
	vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
	vertexBufferDesc.ByteWidth = sizeof(VertexType) * m_vertexCount;
	vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	vertexBufferDesc.CPUAccessFlags = 0;
	vertexBufferDesc.MiscFlags = 0;
	vertexBufferDesc.StructureByteStride = 0;

	// Give the subresource structure a pointer to the vertex data.
	vertexData.pSysMem = vertices;
	vertexData.SysMemPitch = 0;
	vertexData.SysMemSlicePitch = 0;

	// Now create the vertex buffer.
	result = device->CreateBuffer(&vertexBufferDesc, &vertexData, &m_vertexBuffer);
	if(FAILED(result))
	{
		return false;
	}

	// Set up the description of the static index buffer.
	indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
	indexBufferDesc.ByteWidth = sizeof(unsigned long) * m_indexCount;
	indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
	indexBufferDesc.CPUAccessFlags = 0;
	indexBufferDesc.MiscFlags = 0;
	indexBufferDesc.StructureByteStride = 0;

	// Give the subresource structure a pointer to the index data.
	indexData.pSysMem = indices;
	indexData.SysMemPitch = 0;
	indexData.SysMemSlicePitch = 0;

	// Create the index buffer.
	result = device->CreateBuffer(&indexBufferDesc, &indexData, &m_indexBuffer);
	if(FAILED(result))
	{
		return false;
	}

	// Release the arrays now that the vertex and index buffers have been created and loaded.
	delete [] vertices;
	vertices = 0;

	delete [] indices;
	indices = 0;

	return true;


}

void TriangleTest::ShutdownBuffers()
{
	// Release the index buffer.
	if(m_indexBuffer)
	{
		m_indexBuffer->Release();
		m_indexBuffer = 0;
	}

	// Release the vertex buffer.
	if(m_vertexBuffer)
	{
		m_vertexBuffer->Release();
		m_vertexBuffer = 0;
	}

	return;
	// Release the index buffer.
	if(m_indexBuffer)
	{
		m_indexBuffer->Release();
		m_indexBuffer = 0;
	}

	// Release the vertex buffer.
	if(m_vertexBuffer)
	{
		m_vertexBuffer->Release();
		m_vertexBuffer = 0;
	}
	return;
}

void TriangleTest::RenderBuffers(ID3D11DeviceContext* deviceContext)
{
	unsigned int stride;
	unsigned int offset;


	// Set vertex buffer stride and offset.
	stride = sizeof(VertexType); 
	offset = 0;

	// Set the vertex buffer to active in the input assembler so it can be rendered.
	deviceContext->IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &offset);

	// Set the index buffer to active in the input assembler so it can be rendered.
	deviceContext->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R32_UINT, 0);

	// Set the type of primitive that should be rendered from this vertex buffer, in this case triangles.
	deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);

	return;
}

bool TriangleTest::LoadTexture(ID3D11Device*)
{
	return true;
}

void  TriangleTest::ReleaseTexture()
{

}

bool TriangleTest::InitializeShaders(ID3D11Device* device, WCHAR* fileName, CHAR* entryFuncName)
{
	m_vs = new TestVS("TriangleTestVS");
	m_vs->Initialize(device, SystemClass::GetWindowHandler());
	ShaderManager::GetInstance()->InsertShader(SHADER_TYPE_VS, m_vs);
	m_ps = new TestPS();
	m_ps->Initialize(device, SystemClass::GetWindowHandler());
	ShaderManager::GetInstance()->InsertShader(SHADER_TYPE_PS, m_ps);
	return true;
}
